﻿using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;

namespace GooJaCharts
{
    class MyWebPartEditor : System.Web.UI.WebControls.WebParts.EditorPart
    {
        protected Panel m_EditorPanel;
        protected TextBox m_SiteBox;
        protected DropDownList m_ListBox;
        protected SPWeb m_SpWeb;
        protected SPList m_SpList;
        protected DropDownList m_ViewBox;
        protected DropDownList m_XFieldNames;
        protected DropDownList m_YFieldNames;
        protected DropDownList m_Y2FieldNames;

        private enum DisplayType { InitialDisplay, UpdatingDisplay };

        private GooJaChartsPart MyWebPart { get { return this.WebPartToEdit as GooJaChartsPart; } }

        protected override void CreateChildControls()
        {
            this.Title = "GooJaChart Properties";

            m_EditorPanel = new Panel();
            if (SharePointCompilationUtil.SpVer.SpVerNumber == 2007)
            {
                m_EditorPanel.CssClass = "ms-ToolPartSpacing";
            }
            this.Controls.Add(m_EditorPanel);

            AddControlSection(m_EditorPanel, "Site", CreateSiteChoiceControls());
            AddControlSection(m_EditorPanel, "List", CreateListChoiceControl());
            m_ViewBox = new DropDownList(); AddControlSection(m_EditorPanel, "View", m_ViewBox);
            m_XFieldNames = new DropDownList(); AddControlSection(m_EditorPanel, "X Field", m_XFieldNames);
            m_YFieldNames = new DropDownList(); AddControlSection(m_EditorPanel, "Y Field", m_YFieldNames);
            m_Y2FieldNames = new DropDownList(); AddControlSection(m_EditorPanel, "Y2 Field", m_Y2FieldNames);

            base.CreateChildControls();
            this.ChildControlsCreated = true;
        }
        protected override void OnUnload(EventArgs e)
        {
            base.OnUnload(e);
            ClearSpObjects();
        }
        private void ClearSpObjects()
        {
            if (m_SpWeb != null)
            {
                m_SpWeb.Dispose();
                m_SpWeb = null;
            }
        }
        private List<WebControl> CreateSiteChoiceControls()
        {
            List<WebControl> ctls = new List<WebControl>(2);
            m_SiteBox = new TextBox();
            ctls.Add(m_SiteBox);
            ImageButton AcceptButton = new ImageButton();
            ctls.Add(AcceptButton);
            string layoutsdir = "_layouts/GooJaCharts" + SharePointCompilationUtil.SpVer.SpVerString + "/";
            AcceptButton.ImageUrl = PerryUtil.UrlUtil.Cat(SPContext.Current.Web.ServerRelativeUrl, layoutsdir + "checkmark.png");
            AcceptButton.Click += new System.Web.UI.ImageClickEventHandler(AcceptButton_Click);
            return ctls;
        }
        private WebControl CreateListChoiceControl()
        {
            m_ListBox = new DropDownList();
            m_ListBox.SelectedIndexChanged += new EventHandler(m_ListBox_SelectedIndexChanged);
            m_ListBox.AutoPostBack = true;
            return m_ListBox;
        }
        private void AddControlSection(WebControl parent, string title, WebControl child)
        {
            List<WebControl> ctls = new List<WebControl>(1);
            ctls.Add(child);
            AddControlSection(parent, title, ctls);
        }
        private void AddControlSection(WebControl parent, string title, List<WebControl> children)
        {
            Panel sectionPanel = new Panel();
            AddLiteral(sectionPanel, "<div class='UserSectionHead'>" + title + "</div>");
            AddLiteral(sectionPanel, "<div class='UserSectionBody'><div class='UserControlGroup'><nobr>");

            foreach (WebControl ctl in children)
            {
                sectionPanel.Controls.Add(ctl);
            }

            AddLiteral(sectionPanel, "</nobr></div></div>");

            parent.Controls.Add(sectionPanel);
        }
        /// <summary>
        /// Create a literal control holding specified html content
        /// </summary>
        /// <param name="html"></param>
        private void AddLiteral(WebControl ctl, string html)
        {
            ctl.Controls.Add(new System.Web.UI.LiteralControl(html));
        }
        /// <summary>
        /// When creating editor, copy data from web part out to editor controls to display
        /// </summary>
        public override void SyncChanges()
        {
            EnsureChildControls();
            LoadInitialValues();
        }
        private void LoadInitialValues()
        {
            m_SiteBox.Text = MyWebPart.SiteUrl;
            LoadLists(DisplayType.InitialDisplay);
            LoadViewsAndFields(DisplayType.InitialDisplay);
        }
        private void LoadLists(DisplayType displayType)
        {
            string desiredListName = (displayType == DisplayType.InitialDisplay ? MyWebPart.ListName : m_ListBox.SelectedValue);
            m_SpList = null;
            m_ListBox.Items.Clear();
            if (m_SiteBox.Text != "")
            {
                LoadListsFromWebUrl(m_SiteBox.Text, desiredListName);
            }
            else
            {
                LoadListsFromWeb(SPContext.Current.Web, desiredListName);
            }
        }
        public static bool EqStr(string str1, string str2)
        {
            bool ignoreCase = true;
            return string.Compare(str1, str2, ignoreCase) == 0;
        }
        private void LoadListsFromWebUrl(string url, string desiredListName)
        {
            try
            {
                using (SPSite site = new SPSite(m_SiteBox.Text))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        LoadListsFromWeb(web, desiredListName);
                    }
                }
            }
            catch
            {
            }
        }
        private void LoadListsFromWeb(SPWeb web, string desiredListName)
        {
            bool foundDesired = false;
            foreach (SPList list in web.Lists)
            {
                if (list.Hidden) continue;
                if (m_SpList == null) m_SpList = list; // default to first list
                bool selected = EqStr(list.Title, desiredListName);
                m_ListBox.Items.Add(CreateListItem(list.Title, list.Title, selected, ref foundDesired));
                if (selected)
                {
                    m_SpList = list;
                }
            }
        }
        private void LoadViewsAndFields(DisplayType displayType)
        {
            LoadViews(displayType);
            LoadFields(displayType);
        }
        private void UpdateListsAndViews()
        {
            LoadLists(DisplayType.UpdatingDisplay);
            LoadViewsAndFields(DisplayType.UpdatingDisplay);
        }
        private void LoadViews(DisplayType displayType)
        {
            string desiredViewName = (displayType == DisplayType.InitialDisplay ? MyWebPart.ViewName : m_ViewBox.SelectedValue);
            m_ViewBox.Items.Clear();
            if (m_SpList == null) return;
            bool foundDesired = false;
            m_ViewBox.Items.Add(CreateListItem("(Default View)", "", false, ref foundDesired));
            foreach (SPView view in m_SpList.Views)
            {
                m_ViewBox.Items.Add(CreateListItem(view.Title, view.Title, EqStr(view.Title, desiredViewName), ref foundDesired));
            }
            // select "(Default View)" if no view selected
            if (m_ViewBox.SelectedIndex == -1)
            {
                m_ViewBox.SelectedIndex = 0;
            }
        }
        private void LoadFields(DisplayType displayType)
        {
            string desiredXFieldName = (displayType == DisplayType.InitialDisplay ? MyWebPart.XValue : m_XFieldNames.SelectedValue);
            string desiredYFieldName = (displayType == DisplayType.InitialDisplay ? MyWebPart.YValue : m_YFieldNames.SelectedValue);
            string desiredY2FieldName = (displayType == DisplayType.InitialDisplay ? MyWebPart.Y2Value : m_Y2FieldNames.SelectedValue);
            m_XFieldNames.Items.Clear();
            m_YFieldNames.Items.Clear();
            m_Y2FieldNames.Items.Clear();
            if (m_SpList == null) return;
            bool foundDesiredX = false;
            bool foundDesiredY = false;
            bool foundDesiredY2 = false;
            m_Y2FieldNames.Items.Add(CreateListItem("(None)", "", string.IsNullOrEmpty(desiredY2FieldName), ref foundDesiredY2));
            foreach (SPField field in m_SpList.Fields)
            {
                if (field.Hidden) continue;
                m_XFieldNames.Items.Add(CreateListItem(field.Title, field.Title, EqStr(field.Title, desiredXFieldName), ref foundDesiredX));
                m_YFieldNames.Items.Add(CreateListItem(field.Title, field.Title, EqStr(field.Title, desiredYFieldName), ref foundDesiredY));
                m_Y2FieldNames.Items.Add(CreateListItem(field.Title, field.Title, EqStr(field.Title, desiredY2FieldName), ref foundDesiredY2));
            }
        }
        private ListItem CreateListItem(string title, string value, bool selected, ref bool itemSelected)
        {
            ListItem item = new ListItem(title, value);
            if (selected && !itemSelected)
            {
                item.Selected = selected;
                itemSelected = true;
            }
            return item;
        }
        /// <summary>
        /// When user clicks OK or Apply, copy data onscreen in editor part back to web part
        /// </summary>
        /// <returns></returns>
        public override bool ApplyChanges()
        {
            EnsureChildControls();

            GooJaChartsPart webPart = MyWebPart;
            if (webPart == null) return false;
            webPart.SiteUrl = m_SiteBox.Text;
            webPart.ListName = m_ListBox.SelectedValue;
            webPart.ViewName = m_ViewBox.SelectedValue;
            webPart.XValue = m_XFieldNames.SelectedValue;
            webPart.YValue = m_YFieldNames.SelectedValue;
            webPart.Y2Value = m_Y2FieldNames.SelectedValue;
            return true;
        }
        void AcceptButton_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        {
            UpdateListsAndViews();
        }
        void m_ListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateListsAndViews();
        }
    }
}
